package com.xyy.saas.payment.payment.core.adapter;

import com.xyy.saas.payment.adpater.config.BankConfigManager;
import com.xyy.saas.payment.common.Constants;
import com.xyy.saas.payment.common.enums.SettlementStatusEnum;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.OrderTypeEnum;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.cores.param.ProfitSharingDetail;
import com.xyy.saas.payment.cores.param.ProfitSharingParam;
import com.xyy.saas.payment.dao.model.ProfitSharing;
import com.xyy.saas.payment.dao.model.RefundOrder;
import com.xyy.saas.payment.dao.model.ThirdUserInfo;
import com.xyy.saas.payment.payment.core.dto.ChannelAndOrderNoDto;
import com.xyy.saas.payment.payment.core.service.PayOrderService;
import com.xyy.saas.payment.payment.core.service.RefundOrderService;
import com.xyy.saas.payment.service.PayAccountService;
import com.xyy.saas.payment.service.ThirdUserInfoService;
import com.xyy.saas.payment.util.DateUtil;
import com.xyy.saas.payment.util.LeafUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Component
public class TransformAdapter {
    @Resource
    private BankConfigManager bankConfigManager;
    @Resource
    private LeafUtil leafUtil;
    @Resource
    private PayAccountService payAccountService;
    @Resource
    private PayOrderService payOrderService;
    @Resource
    private RefundOrderService refundOrderService;
    @Resource
    private ThirdUserInfoService thirdUserInfoService;

    /**
     * 分润汇总
     * @param profitsharingParam
     * @return
     * @throws PaymentException
     */
    public ProfitSharing transformProfitSharing(ProfitSharingParam profitsharingParam) throws PaymentException {
        if(profitsharingParam == null) {
            throw new PaymentException(ResultCodeEnum.PARAM_SUBJECT_ERROR);
        }

        if(!profitsharingParam.getTotalPayAmount().equals(profitsharingParam.getTotalBalancePayAmount() + profitsharingParam.getTotalOnlinePayAmount())) {
            throw new PaymentException(ResultCodeEnum.PROFIT_SHARING_SETTLE_BALANCE_PAY_AMOUNT_ERROR);
        }

        ProfitSharing profitSharing = new ProfitSharing();
        profitSharing.setMerchantNo(bankConfigManager.getFuminBankMch(profitsharingParam.getBusinessOrderType().getType()));
        profitSharing.setAccountId(payAccountService.getAccountIdByBusiness(profitsharingParam.getBusinessIdType().getType(), profitsharingParam.getBusinessId()));
        profitSharing.setBusinessOrderType(profitsharingParam.getBusinessOrderType().getType());
        profitSharing.setCallback(profitsharingParam.getCallback());
        profitSharing.setProfitSharingNo(leafUtil.getSnowflakeId());
        profitSharing.setBusinessOrderNo(profitsharingParam.getBusinessOrderNo());
        profitSharing.setBusinessName(profitsharingParam.getBusinessName());
        profitSharing.setTotalGoodsAmount(profitsharingParam.getTotalGoodsAmount());
        profitSharing.setTotalFreightAmount(profitsharingParam.getTotalFreightAmount());
        profitSharing.setTotalAmount(profitsharingParam.getTotalAmount());
        profitSharing.setTotalStoreDiscountAmount(profitsharingParam.getTotalStoreDiscountAmount());
        profitSharing.setTotalPlatformDiscountAmount(profitsharingParam.getTotalPlatformDiscountAmount());
        profitSharing.setTotalPayAmount(profitsharingParam.getTotalPayAmount());
        profitSharing.setTotalBalancePayAmount(profitsharingParam.getTotalBalancePayAmount());
        profitSharing.setTotalOnlinePayAmount(profitsharingParam.getTotalOnlinePayAmount());
        profitSharing.setTotalBrokerageAmount(profitsharingParam.getTotalBrokerageAmount());
        profitSharing.setTotalSettleAmount(profitsharingParam.getTotalSettleAmount());
        profitSharing.setStatus(SettlementStatusEnum.PENDING.getStatus());
        profitSharing.setMessage(SettlementStatusEnum.PENDING.getDesc());
        return profitSharing;
    }


    /**
     * 分润详情
     * @param profitSharingNo
     * @param profitsharingParam
     * @return
     * @throws PaymentException
     */
    public List<com.xyy.saas.payment.dao.model.ProfitSharingDetail> transformProfitSharingDetail(String profitSharingNo,
        ProfitSharingParam profitsharingParam) throws PaymentException
    {
        // 参数校验
        if(profitsharingParam == null || CollectionUtils.isEmpty(profitsharingParam.getDetails())) {
            throw new PaymentException(ResultCodeEnum.PARAM_SUBJECT_ERROR);
        }
        // 获取子账户信息
        ThirdUserInfo thirdUserInfo = thirdUserInfoService.getThirdUserInfoByUserId(payAccountService.getAccountIdByBusiness(profitsharingParam.getBusinessIdType().getType(), profitsharingParam.getBusinessId()));
        // 获取传入的明细数据
        List<ProfitSharingDetail> details = profitsharingParam.getDetails();
        List<com.xyy.saas.payment.dao.model.ProfitSharingDetail> result = new ArrayList<>();
        // 循环传入明细数据，转换为ProfitSharingDetail数据
        for(ProfitSharingDetail detail : details) {
            // 实付金额 = 购物金/余额实付金额 + 现金/在线实付金额
            if(!detail.getPayAmount().equals(detail.getBalancePayAmount() + detail.getOnlinePayAmount())) {
                throw new PaymentException(ResultCodeEnum.PROFIT_SHARING_SETTLE_BALANCE_PAY_AMOUNT_ERROR);
            }
            com.xyy.saas.payment.dao.model.ProfitSharingDetail item = new com.xyy.saas.payment.dao.model.ProfitSharingDetail();
            item.setProfitSharingNo(profitSharingNo);
            item.setBusinessOrderNo(profitsharingParam.getBusinessOrderNo());
            item.setOrderType(detail.getOrderType().getType());
            item.setOrderNo(detail.getOrderNo());
            item.setBuyerName(detail.getBuyerName());
            item.setGoodsAmount(detail.getGoodsAmount());
            item.setFreightAmount(detail.getFreightAmount());
            item.setAmount(detail.getAmount());
            item.setStoreDiscountAmount(detail.getStoreDiscountAmount());
            item.setPlatformDiscountAmount(detail.getPlatformDiscountAmount());
            item.setPayAmount(detail.getPayAmount());
            item.setBalancePayAmount(detail.getBalancePayAmount());
            item.setOnlinePayAmount(detail.getOnlinePayAmount());
            item.setBrokerageAmount(detail.getBrokerageAmount());
            item.setSettleAmount(detail.getSettleAmount());

            if(OrderTypeEnum.PAY.equals(detail.getOrderType())) {
                // 现金/在线实付金额 != 0
                if(!NumberUtils.INTEGER_ZERO.equals(detail.getOnlinePayAmount())) {
                    // 查询pay_result_order获取支付渠道、订单号、交易日期
                    ChannelAndOrderNoDto channelAndOrderNoDto = payOrderService.getPayChannelAndOrderNo(profitsharingParam.getBusinessOrderType().getType(), detail.getOrderNo(), detail.getOnlinePayAmount(), thirdUserInfo.getThirdType());
                    item.setPayChannel(channelAndOrderNoDto.getChannel());
                    item.setPaymentOrderNo(channelAndOrderNoDto.getOrderNo());
                    item.setPaymentTradeDate(channelAndOrderNoDto.getTradeDate());
                } else {
                    // 购物金支付
                    item.setPayChannel(Constants.CHANNEL_BALANCE_NAME);
                    item.setPaymentOrderNo(StringUtils.EMPTY);
                    item.setPaymentTradeDate(DateUtil.now());
                }
            }
            else if(OrderTypeEnum.REFUND.equals(detail.getOrderType())) {
                // 现金/在线实付金额 != 0
                if(!NumberUtils.INTEGER_ZERO.equals(detail.getOnlinePayAmount())) {
                    RefundOrder refundOrder = refundOrderService.selectByBusinessRefundNo(detail.getOrderNo());
                    if(refundOrder == null) {
                        throw new PaymentException(ResultCodeEnum.TRADE_NOT_EXIT_ERROR);
                    }
                    // 退款金额 != 现金/在线实付金额
                    if(!Objects.equals(refundOrder.getAmount(), Math.abs(detail.getOnlinePayAmount()))) {
                        throw new PaymentException(ResultCodeEnum.PARAM_ERROR.getCode(), "Detail pay amount not match, businessOrderNo=" + refundOrder.getBusinessRefundNo());
                    }
                    item.setPayChannel(refundOrder.getChannel());
                    item.setPaymentOrderNo(refundOrder.getRefundNo());
                    item.setPaymentTradeDate(refundOrder.getSuccessTime());
                }
                else {
                    // 购物金退
                    item.setPayChannel(Constants.CHANNEL_BALANCE_NAME);
                    item.setPaymentOrderNo(StringUtils.EMPTY);
                    item.setPaymentTradeDate(DateUtil.now());
                }
            }

            result.add(item);
        }

        return result;
    }
}